package test.serverframe.armc.server.manager.config;


import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * @Description Druid监控统计功能
 * @Author LSY
 * @Date 2018/9/14 11:00
 * @ClassName com.example.beanApplicationDruidConfig
 */
@Configuration
public class DruidConfiguration{
    private static final Logger logger = LoggerFactory.getLogger(DruidConfiguration.class);

    private static final String DB_PREFIX = "spring.datasource";

    @Bean
    public ServletRegistrationBean druidServlet() {
        logger.info("init Druid Servlet Configuration ");
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        // IP白名单
        servletRegistrationBean.addInitParameter("allow", "192.168.1.153,127.0.0.1");
        // IP黑名单(共同存在时，deny优先于allow)
        servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
        //控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername", "admin");
        servletRegistrationBean.addInitParameter("loginPassword", "admin");
        //是否能够重置数据 禁用HTML页面上的“Reset All”功能
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }

    //解决 spring.datasource.filters=stat,wall,log4j 无法正常注册进去
    @ConfigurationProperties(prefix = DB_PREFIX)
    class IDataSourceProperties {
        private String url;
        private String username;
        private String password;
        private String driver_class_namel;
        private String type;
        private int max_active;
        private int initial_size;
        private int min_idle;
        private int max_wait;
        private int time_between_eviction_runs_millis;
        private int min_evictable_idle_time_millis;
        private boolean test_while_idle;
        private boolean test_on_borrow;
        private boolean test_on_return;
        private boolean poolPreparedStatements;

        @Bean     //声明其为Bean实例
        @Primary  //在同样的DataSource中，首先使用被标注的DataSource
        public DataSource dataSource() {
            DruidDataSource datasource = new DruidDataSource();
            datasource.setUrl(url);
            datasource.setUsername(username);
            datasource.setPassword(password);
            datasource.setDriverClassName(driver_class_namel);

            //configuration
            datasource.setInitialSize(initial_size);
            datasource.setMinIdle(min_idle);
            datasource.setMaxActive(max_active);
            datasource.setMaxWait(max_wait);
            datasource.setTimeBetweenEvictionRunsMillis(time_between_eviction_runs_millis);
            datasource.setMinEvictableIdleTimeMillis(min_evictable_idle_time_millis);
//            datasource.setValidationQuery(validationQuery);
            datasource.setTestWhileIdle(test_while_idle);
            datasource.setTestOnBorrow(test_on_borrow);
            datasource.setTestOnReturn(test_on_return);
            datasource.setPoolPreparedStatements(poolPreparedStatements);
//            datasource.setMaxPoolPreparedStatementPerConnectionSize(poolPreparedStatements);
            try {
                datasource.setFilters("stat,wall,slf4j");
            } catch (SQLException e) {
                System.err.println("druid configuration initialization filter: " + e);
            }
//            datasource.setConnectionProperties(connectionProperties);
            return datasource;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getDriver_class_namel() {
            return driver_class_namel;
        }

        public void setDriver_class_namel(String driver_class_namel) {
            this.driver_class_namel = driver_class_namel;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public int getMax_active() {
            return max_active;
        }

        public void setMax_active(int max_active) {
            this.max_active = max_active;
        }

        public int getInitial_size() {
            return initial_size;
        }

        public void setInitial_size(int initial_size) {
            this.initial_size = initial_size;
        }

        public int getMin_idle() {
            return min_idle;
        }

        public void setMin_idle(int min_idle) {
            this.min_idle = min_idle;
        }

        public int getMax_wait() {
            return max_wait;
        }

        public void setMax_wait(int max_wait) {
            this.max_wait = max_wait;
        }

        public int getTime_between_eviction_runs_millis() {
            return time_between_eviction_runs_millis;
        }

        public void setTime_between_eviction_runs_millis(int time_between_eviction_runs_millis) {
            this.time_between_eviction_runs_millis = time_between_eviction_runs_millis;
        }

        public int getMin_evictable_idle_time_millis() {
            return min_evictable_idle_time_millis;
        }

        public void setMin_evictable_idle_time_millis(int min_evictable_idle_time_millis) {
            this.min_evictable_idle_time_millis = min_evictable_idle_time_millis;
        }

        public boolean isTest_while_idle() {
            return test_while_idle;
        }

        public void setTest_while_idle(boolean test_while_idle) {
            this.test_while_idle = test_while_idle;
        }

        public boolean isTest_on_borrow() {
            return test_on_borrow;
        }

        public void setTest_on_borrow(boolean test_on_borrow) {
            this.test_on_borrow = test_on_borrow;
        }

        public boolean isTest_on_return() {
            return test_on_return;
        }

        public void setTest_on_return(boolean test_on_return) {
            this.test_on_return = test_on_return;
        }

        public boolean isPoolPreparedStatements() {
            return poolPreparedStatements;
        }

        public void setPoolPreparedStatements(boolean poolPreparedStatements) {
            this.poolPreparedStatements = poolPreparedStatements;
        }
    }
}
